package cn.lhl01.sys.handler;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.lhl01.common.Results;
import cn.lhl01.sys.constant.SidEnum;
import cn.lhl01.sys.entity.vo.ParameterRequestWrapper;
import cn.lhl01.util.PasswordUtil;
import cn.lhl01.util.Utils;
import com.alibaba.fastjson2.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;

/**
 * 基于Filter 解密转发
 */
@Slf4j
//@Component
@RequiredArgsConstructor
public class ReqPerHandler extends OncePerRequestFilter {
	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
		response.setContentType("application/json;charset=utf-8");
		String path = request.getRequestURI();
		if (path == null) {
			log.info("无路径，禁止访问");
			Utils.results(response, Results.accessDenied());
		} else if (path.startsWith("/login") || path.startsWith("/favicon.ico")) {
			chain.doFilter(request, response);
		} else {


			Date startOn = DateTime.now();
			long startTime = System.currentTimeMillis();
			boolean success = true;

			String clientIP = ServletUtil.getClientIP(request);
			System.out.println("ip>>>:" + clientIP);

			clientIP = Utils.getRemoteAddr(request);
			System.out.println("ip>>>:" + clientIP);
			log.info("class>>>:" + this);
			String contentType = request.getContentType();

			//接收form参数
			if (!StrUtil.containsAnyIgnoreCase(contentType, "form-data")) {
				Results paramError = Results.paramError("contentType需要form-data");
				Utils.results(response, paramError);
				return;
			}

			String timestamp = request.getParameter("timestamp");
			String echostr = request.getParameter("echostr");
			String signature = request.getParameter("signature");
			String mi = request.getParameter("param");

			//验证timestamp 超时 超过2分钟的不接受
//		if (startTime - NumberUtil.parseLong(timestamp) > 1000 * 60 *2) {
//			Results paramError = Results.paramError("过时的请求");
//			Utils.results(response, paramError);
//			return;
//		}


			//生成验签串
			String serverSignature = SecureUtil.md5(echostr + "θ" + timestamp + "θ" + mi);
			if (!signature.equals(serverSignature)) {
				//throw new BusinessException(MessageCodes.SIGN_FAILED);
				//验签失败 {"PARAMS":{"mineCode":"10003","mineName":"老石旦煤矿","orderCode":"167651641531300009","payment":1,"sysCode":"1001","userCode":"10779301"},"SID":110002}
				System.out.println("验签失败");
				Results paramError = Results.paramError("验签失败");
				Utils.results(response, paramError);
				return;
			}

			//解密
			String ming = SecureUtil.aes(PasswordUtil.AES_KEY.getBytes()).decryptStr(mi);

			log.info("ming>>>:" + ming);
			JSONObject jsonObject = JSONObject.parseObject(ming);

			Integer sid = (Integer) jsonObject.get("SID");
			JSONObject params = (JSONObject) jsonObject.get("PARAMS");
			//明文参数转map
			HashMap hashMapParams = JSONObject.parseObject(params.toString(), HashMap.class);

			//sid映射
			SidEnum sidEnum = SidEnum.map_EnumConstant.get(sid);
			if (null == sidEnum) {
				Results paramError = Results.paramError("sid不存在");
				Utils.results(response, paramError);
				return;
			}

			//转发
			ParameterRequestWrapper parameterRequestWrapper = new ParameterRequestWrapper(request, hashMapParams);
			RequestDispatcher requestDispatcher = parameterRequestWrapper.getRequestDispatcher(sidEnum.getUrl());
			requestDispatcher.forward(parameterRequestWrapper, response);
		}
	}

}
